from django.db import models
from django.conf import settings
from django.utils.html import format_html
import binascii
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


# Create your models here.


class HostsInfo(models.Model):
    """
    远程主机信息
    """
    IS_DELETED_CHOICES = (
        (1, "无效"),
        (0, "有效"),
    )

    host_flag = models.CharField(verbose_name="主机标识", max_length=100, unique=True, null=False, blank=False,
                                 help_text="主机标识")
    ip = models.CharField(verbose_name="主机ip", max_length=50, null=False, blank=False, help_text="主机ip")
    port = models.IntegerField(verbose_name="主机端口", null=False, blank=False, default=22, help_text="主机端口")
    username = models.CharField(verbose_name="登录用户", max_length=100, null=False, blank=False, help_text="登录用户")
    password = models.CharField(verbose_name="登录密码", max_length=256, null=False, blank=False, help_text="登录密码")
    is_deleted = models.SmallIntegerField(verbose_name="是否删除", default=0, choices=IS_DELETED_CHOICES, help_text="是否删除")
    c_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, help_text="创建时间")
    m_time = models.DateTimeField(verbose_name="修改时间", auto_now=True, help_text="修改时间")

    class Meta:
        db_table = "t_hosts_info"
        ordering = ['-c_time']
        verbose_name = "远程主机信息"
        verbose_name_plural = verbose_name
        unique_together = ['ip', 'port', 'username']

    def __str__(self):
        return '<{0.host_flag}: {0.ip}:{0.port} ({0.username})>'.format(self)

    def colored_is_deleted(self):
        if self.is_deleted == 1:
            color = "red"
        else:
            color = "green"

        return format_html(
            '<span style="color: {};">{}</span>',
            color,
            self.get_is_deleted_display()
        )

    colored_is_deleted.short_description = '主机信息是否有效'

    def save(self, *args, **kwargs):
        # 创建用户时，为用户自动生成个人唯一ID
        self.password = self._encrypt_password(self.password)
        super(HostsInfo, self).save(*args, **kwargs)

    def _encrypt_password(self, password: str):
        """
        加解密的AES对象必须分别实例化
        :param password:
        :return:
        """
        key = bytes(settings.SECRET_KEY[:32], encoding="utf-8")
        iv = bytes(settings.SECRET_KEY[-16:], encoding="utf-8")
        obj_cipher = AES.new(key, AES.MODE_CFB, iv)
        encrypted_msg = obj_cipher.encrypt(pad(bytes(password, encoding="utf-8"), AES.block_size))  # 二进制密文
        encrypted_msg = binascii.b2a_hex(encrypted_msg)  # 将二进制密文转换为16进制显示
        encrypted_msg = str(encrypted_msg, encoding="utf-8")  # 将字节转化为字符串
        return encrypted_msg

    def _decrypt_password(self, encrypted_password: str):
        """
        加解密的AES对象必须分别实例化
        :param encrypted_password:
        :return:
        """
        key = bytes(settings.SECRET_KEY[:32], encoding="utf-8")
        iv = bytes(settings.SECRET_KEY[-16:], encoding="utf-8")
        obj_cipher = AES.new(key, AES.MODE_CFB, iv)
        decrypted_msg = binascii.a2b_hex(bytes(encrypted_password, encoding="utf-8"))  # 将二进制密文转换为16进制显示
        decrypted_msg = unpad(obj_cipher.decrypt(decrypted_msg), AES.block_size)  # 二进制密文
        decrypted_msg = str(decrypted_msg, encoding="utf-8")  # 将字节转化为字符串
        return decrypted_msg

    def get_password(self):
        password = self._decrypt_password(self.password)
        return password
